/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.bomberman.world;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.LoopMode;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Node;
import de.bomberman.appstate.MainApp;
import de.bomberman.bomb.Bomb;
import java.util.logging.Logger;

/**
 *
 * @author Mats
 */
public class Player {

    private InputManager inputManager;
    private AssetManager assetManager;
    private Node rootNode;
    private Node playerNode;
    // for physics
    private static CharacterControl physics;
    private CapsuleCollisionShape collisionShape;
    // for the animation of the character
    private AnimChannel animChannel;
    private AnimControl animControl;
    // for controlling the walking process
    boolean walkLeft, walkRight, walkUp, walkDown;
    private MainApp app;
    // Logger
    private static final Logger logger = Logger.getLogger(Player.class.getName());

    public Player(Node rootNode, float playerSize, MainApp app) {

        this.assetManager = app.getAssetManager();
        this.inputManager = app.getInputManager();
        this.rootNode = rootNode;
        this.app = app;

        // init player node
        playerNode = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
        playerNode.setLocalScale(0.15f);
        playerNode.setLocalTranslation(1, 6, 1);
        playerNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);

        initKeys();

        // init player physics
        collisionShape = new CapsuleCollisionShape(0.5f, 0.5f);
        physics = new CharacterControl(collisionShape, 0.1f);
        playerNode.addControl(physics);

        // init the animation of the player
        animControl = playerNode.getControl(AnimControl.class);
        animChannel = animControl.createChannel();
        animChannel.setAnim("stand");
    }

    private void initKeys() {
        inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_U));
        inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_J));
        inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_H));
        inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_K));
        inputManager.addMapping("DropBomb", new KeyTrigger(KeyInput.KEY_SPACE));

        String[] walkKeys = new String[]{"Up", "Down", "Left", "Right"};
        inputManager.addListener(waklListenerAnalog, walkKeys);
        inputManager.addListener(walkListenerAction, walkKeys);
        inputManager.addListener(dropBombAction, "DropBomb");

    }
    private AnalogListener waklListenerAnalog = new AnalogListener() {
        @Override
        public void onAnalog(String name, float value, float tpf) {
            // walkspeed depens on the time per frame value
            float walkSpeed = 5f * tpf;

            if (walkUp || walkDown || walkLeft || walkRight) {
                // start animation
                if (!animChannel.getAnimationName().equals("Walk")) {

                    animChannel.setAnim("Walk", 0.50f);
                    animChannel.setSpeed(walkSpeed);
                    animChannel.setLoopMode(LoopMode.Loop);
                    walk(walkSpeed);
                }

                if (walkUp) {
                    physics.setWalkDirection(new Vector3f(0, 0, -walkSpeed));
                    physics.setViewDirection(new Vector3f(0, 0, -walkSpeed));
                }
                if (walkDown) {
                    physics.setWalkDirection(new Vector3f(0, 0, walkSpeed));
                    physics.setViewDirection(new Vector3f(0, 0, walkSpeed));
                }
                if (walkLeft) {
                    physics.setWalkDirection(new Vector3f(-walkSpeed, 0, 0));
                    physics.setViewDirection(new Vector3f(-walkSpeed, 0, 0));
                }
                if (walkRight) {
                    physics.setWalkDirection(new Vector3f(walkSpeed, 0, 0));
                    physics.setViewDirection(new Vector3f(walkSpeed, 0, 0));
                }
            } else {
                // end animation
                animChannel.setAnim("stand", 0.50f);
                animChannel.setLoopMode(LoopMode.DontLoop);
                animChannel.setSpeed(1f);
                physics.setWalkDirection(new Vector3f(0, 0, 0));
            }
        }
    };
    private ActionListener walkListenerAction = new ActionListener() {
        @Override
        public void onAction(String name, boolean keyPressed, float tpf) {
            switch (name) {
                case "Up":
                    walkUp = keyPressed;
                    break;
                case "Down":
                    walkDown = keyPressed;
                    break;
                case "Left":
                    walkLeft = keyPressed;
                    break;
                case "Right":
                    walkRight = keyPressed;
                    break;
            }
        }
    };

    public void walk(float walkSpeed) {
        physics.setWalkDirection(new Vector3f(physics.getViewDirection().getX() * 0.05f * walkSpeed,
                physics.getViewDirection().getY() * 0.05f * walkSpeed,
                physics.getViewDirection().getZ() * 0.05f * walkSpeed));
        animChannel.setAnim("Walk", 0.50f);
    }
    private ActionListener dropBombAction = new ActionListener() {
        @Override
        public void onAction(String name, boolean keyPressed, float tpf) {
            if (name.equals("DropBomb") && !keyPressed) {
                dropBomb();

            }
        }
    };

    public void dropBomb() {


        int x = (int) (physics.getPhysicsLocation().x + 0.5);
        int y = (int) (physics.getPhysicsLocation().y + 0.5);
        int z = (int) (physics.getPhysicsLocation().z + 0.5);
        Vector3f location = new Vector3f(x, y, z);

        Bomb bomb = new Bomb(assetManager, location, app);
        rootNode.attachChild(bomb.getBombNode());


        DefaultLevel.field[x][z].setType(FIELD_TYPE.BOMB);




    }

    public CharacterControl getPhysics() {
        return physics;
    }

    public Node getPlayerNode() {
        return playerNode;
    }
    private static int playerX, playerY, playerZ;

    public static Vector3f getCurrentLocation() {
        playerX = (int) (physics.getPhysicsLocation().x + 0.5);
        playerY = (int) (physics.getPhysicsLocation().y + 0.5);
        playerZ = (int) (physics.getPhysicsLocation().z + 0.5);
        Vector3f location = new Vector3f(playerX, playerY, playerZ);
        return location;
    }
}
